import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JFrame;
import javax.swing.JPanel;

import wpspider.client.model.Page;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.graph.Vertex;
import edu.uci.ics.jung.graph.impl.DirectedSparseEdge;
import edu.uci.ics.jung.graph.impl.DirectedSparseGraph;
import edu.uci.ics.jung.graph.impl.DirectedSparseVertex;
import edu.uci.ics.jung.utils.UserData;
import edu.uci.ics.jung.visualization.FRLayout;
import edu.uci.ics.jung.visualization.Layout;
import edu.uci.ics.jung.visualization.PluggableRenderer;
import edu.uci.ics.jung.visualization.ShapePickSupport;
import edu.uci.ics.jung.visualization.SpringLayout;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse;

public class JUNGSample {

    public static void main(String[] args) {
        JFrame frame = new JFrame("Sample");
        frame.setSize(500, 500);
        SampleGraph graph = SampleGraph.getInstance();
        frame.getContentPane().add(graph.getViewer());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Timer timer = new Timer();
        timer.schedule(new RepaintTask(), 1000, 1000);
        frame.setVisible(true);
    }
}

class SampleGraph {
    private static SampleGraph _instance = null;
    private Map<String, Page> _pages;
    private Graph _graph;
    private SpringLayout _layout;
    private VisualizationViewer _viewer;

    private SampleGraph() {
        _pages = new HashMap<String, Page>();
        _graph = new DirectedSparseGraph();
        _layout = new SpringLayout(_graph);
        _viewer = new VisualizationViewer(_layout, new PluggableRenderer());
        _viewer.getModel().setRelaxerThreadSleepTime(500);
        _viewer.setPickSupport(new ShapePickSupport());
        _viewer.setGraphMouse(new DefaultModalGraphMouse());
    }

    public static SampleGraph getInstance() {
        if (_instance == null) {
            _instance = new SampleGraph();
        }
        return _instance;
    }

    public synchronized void setPages(Map<String, Page> pages) {
        _pages = pages;
    }

    public synchronized void addPages(Map<String, Page> pages) {
        _pages.putAll(pages);
    }

    public synchronized void addPage(String name, Page page) {
        _pages.put(name, page);
    }

    public synchronized void removePage(String name) {
        _pages.remove(name);
    }

    public void update() {
        System.out.println("START update");
        Set<String> names = _pages.keySet();
        Set<Vertex> oldVertices = _graph.getVertices();
        Set<Vertex> removalVertices = new HashSet<Vertex>();
        Map<String, Vertex> vertices = new HashMap<String, Vertex>();
        for (Iterator iterator = oldVertices.iterator(); iterator.hasNext();) {
            Vertex vertex = (Vertex) iterator.next();
            Page page = (Page) vertex.getUserDatum("Page");
            System.out.println("update1:" + page.getName());
            if (names.contains(page.getName())) {
                vertices.put(page.getName(), vertex);
            } else {
                removalVertices.add(vertex);
            }
        }
        for (Iterator iterator = removalVertices.iterator(); iterator.hasNext();) {
            _graph.removeVertex((Vertex) iterator.next());
        }
        for (Iterator iterator = names.iterator(); iterator.hasNext();) {
            String name = (String) iterator.next();
            Page page = (Page) _pages.get(name);
            System.out.println("update2:" + name);
            if (!vertices.containsKey(name)) {
                Vertex vertex = _graph.addVertex(new DirectedSparseVertex());
                vertex.addUserDatum("Page", page, UserData.SHARED);
                vertices.put(name, vertex);
            }
        }

        for (Iterator iterator1 = vertices.keySet().iterator(); iterator1.hasNext();) {
            String name1 = (String) iterator1.next();
            Vertex vertex1 = vertices.get(name1);
            Page page1 = (Page) vertex1.getUserDatum("Page");
            for (Iterator iterator2 = page1.getWords().iterator(); iterator2.hasNext();) {
                String name2 = (String) iterator2.next();
                Vertex vertex2 = vertices.get(name2);
                if (vertex2 != null && !vertex1.isNeighborOf(vertex2)) {
                    System.out.println(name1 + ", " + name2);
                    _graph.addEdge(new DirectedSparseEdge(vertex1, vertex2));
                }
            }
        }
        _layout.update();
        _viewer.repaint();
        System.out.println("END update");
    }

    public JPanel getViewer() {
        return _viewer;
    }
}

class RepaintTask extends TimerTask {
    private int _count;

    public RepaintTask() {
        _count = 0;
    }

    public void run() {
        SampleGraph graph = SampleGraph.getInstance();
        Map pages = new HashMap();
        for (int i = 0; i < 3; i++) {
            _count += 1;
            System.out.println("run:" + _count);
            String name = String.valueOf(_count);
            List<String> words = new ArrayList<String>();
            for (int j = 1; j <= 10; j++) {
                words.add(String.valueOf(_count + j));
                Page page = new Page(name, words);
                graph.addPage(name, page);
            }
            int xcount = _count - 20;
            if (0 < xcount) {
                String xname = String.valueOf(xcount);
                graph.removePage(xname);
            }
        }
        graph.update();
    }
}
